#include "TileManager.h"

#include <sstream>
using std::wostringstream;

#include "../SGD Wrappers/CSGD_TextureManager.h"
#include "../Tiny XML/tinyxml.h"

#include "BaseTile.h"
#include "BreakableWallsTile.h"
#include "MoveableTile.h"
#include "SoftWallTile.h"
#include "SpawnTile.h"
#include "TriggerTile.h"

CTileManager* CTileManager::GetInstance( void )
{
	static CTileManager s_Instance;

	return &s_Instance;
}

CTileManager::CTileManager(void)
{
}


CTileManager::~CTileManager(void)
{
}

std::list<CBaseTile*> CTileManager::CreateTiles( void )
{
	// Returns a list, can be used to have a list of "levels" or "areas".
	std::list < CBaseTile* > tempTiles;

	LoadTileInfo( tempTiles );

	return tempTiles;
}

bool CTileManager::LoadTileInfo( std::list< CBaseTile* > &TileList )
{
	TileList.clear();
	CBaseTile* tempTile;

	std::string szLocation;
	int height, width, x, y, OffsetX, OffsetY, TileID;

	TiXmlDocument doc;

	if( doc.LoadFile( "BasicTile.xml" ) )
	{
		TiXmlElement* pRoot = doc.RootElement();

		if( pRoot != nullptr )
		{
			TiXmlElement* pTile = pRoot->FirstChildElement( "Tile" );

			while( pTile != nullptr )
			{
				pTile->Attribute( "Height",	 &height	);
				pTile->Attribute( "Width",	 &width		);
				pTile->Attribute( "PosX",	 &x			);
				pTile->Attribute( "PosY",	 &y			);
				pTile->Attribute( "OffsetX", &OffsetX	);
				pTile->Attribute( "OffsetY", &OffsetY	);
				pTile->Attribute( "TileID",	 &TileID	);

				wostringstream oss;

				const char* pText = pTile->GetText();
				if( pText != nullptr )
					oss << pText;

				switch( TileID )
				{
				case Base:
					tempTile = new CBaseTile;
					break;
				case Breakable:
					tempTile = new CBreakableWallsTile;
					break;
				case Moveable:
					tempTile = new CMoveableTile;
					break;
				case Soft:
					tempTile = new CSoftWallTile;
					break;
				case Spawn:
					tempTile = new CSpawnTile;
					break;
				case Trigger:
					tempTile = new CTriggerTile;
					break;
				}

				tempTile->SetImageID( CSGD_TextureManager::GetInstance()->LoadTexture( (oss.str().c_str()) ) );
				tempTile->SetTileID( TileID );

				tempTile->SetHeight( height );
				tempTile->SetWidth( width );

				tempTile->SetPosX( (float)x );
				tempTile->SetPosY( (float)y );

				tempTile->SetOffset( OffsetX, OffsetY );

				TileList.push_back( tempTile );

				pTile = pTile->NextSiblingElement( "Tile" );
			}
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}

	return true;
}